過濾器可以用來做權限校驗或是編碼轉換等功能。
多個過濾器可以串聯在一起,做多重過濾。
自定義的過濾器需實現javax.servlet.Filter介面。
編碼轉換案例:
@WebFilter(urlPatterns = "/*",
initParams = {@WebInitParam(name = "encoding",value = "utf-8")})
public class CharacterEncodingFilter implements Filter {…}
urlPatterns = "/*" //過濾目標為此網站下所有網頁
initParams = {@WebInitParam(name = "encoding",value = "utf-8")} //將encoding方式設為utf-8(或其他編碼)
public void init(FilterConfig fConfig) throws ServletException {
this.encoding = fConfig.getInitParameter("encoding");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if(encoding != null) {
request.setCharacterEncoding(encoding);
}
HttpServletRequest r = (HttpServletRequest)request;
if(r.getMethod().equalsIgnoreCase("get")) { //只針對GET請求進行過濾,POST方法通常不會亂碼。
Enumeration<?>names = request.getParameterNames();
while(names.hasMoreElements()) {
String[] values = request.getParameterValues(names.nextElement().toString());
for(int i = 0;i < values.length; ++i) {
values[i] = new String(values[i].getBytes("ISO-8859-1"),encoding);
}
}
}
chain.doFilter(request, response); //過濾器處理完後丟給下一個過濾器或引導至資源網頁。
}
權限校驗案例:
@WebServlet("/LoginSvl")
public class LoginSvl extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String uname = request.getParameter("uname");
request.getSession().setAttribute("uname", uname);
String pwd = request.getParameter("pwd");
//request.setAttribute("uname", uname);
request.getRequestDispatcher("/main/hello.jsp").forward(request, response);
}
}
@WebFilter(filterName = "/UserFilter", urlPatterns = "/user/*")
public class UserFilter implements Filter {
(前略…)
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
Object object = req.getSession().getAttribute("uname");
if(object != null) { //這邊因為是範例,所以沒有從資料庫拿使用者名單,只是簡單的從session裡確認是否有uname被儲存了。
chain.doFilter(request, response);
}else {
request.setAttribute("msg", "請先登錄");
req.getRequestDispatcher("/main/login.jsp").forward(request, response);
}
}
}
Hi,${uname}
跑看看過濾器是否起作用吧。
監聽器的種類繁多,用來監聽各種不同對象。不像Filter一樣只有一種。例如:
當伺服器啟動時會創建ServletContext物件,此時利用監聽器即可加載一些初始化資訊。
@WebListener
public class MyContextListener implements ServletContextListener {}
public void contextDestroyed(ServletContextEvent sce) {
}
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Tomcat啟動,ServletContext被創建");
}
一個Session代表一個在線上的用戶,因此可以用監聽器追蹤或管理用戶狀態。
註:統計用戶對象時,如果用戶主動登出,Web應用程式會自動創建另一個會話對象,因此線上人數不會變更。只有用戶超時未操作時,線上人數才會減少。
利用監聽器也可以踢掉不當發言的使用者,流程如下:
@WebListener
public class OnlineUserListerner implements HttpSessionListener {
public static Map<String,HttpSession> allUser;
static {
allUser = new ConcurrentHashMap<>();
}
public void sessionCreated(HttpSessionEvent se) {
HttpSession session = se.getSession();
allUser.put(session.getId(), session);
}
public void sessionDestroyed(HttpSessionEvent se) {
HttpSession session = se.getSession();
allUser.remove(session.getId(), session);
}
}
@WebServlet("/LoginSvl")
public class LoginSvl extends HttpServlet {
private Map<String,String> loginedUsers = new ConcurrentHashMap<>();
(中略…)
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String uname = request.getParameter("uname");
String pwd = request.getParameter("pwd");
LoginBiz biz = new LoginBiz();
User user = biz.login(uname,pwd);
request.getSession().setAttribute("user", uname);
loginedUsers.put(uname, request.getSession().getId());
request.getRequestDispatcher("/main/main.jsp").forward(request, response);
}
}
踢除某用戶的方法
String sessionid = loginedUsers.get(uname);
HttpSession session = OnlineUserListerner.allUser.get(sessionid);
session.invalidate();
監聽每一次用戶訪問紀錄,可用於統計網站被訪問次數,例如:
@WebListener
public class PageViewListener implements ServletRequestListener {
AtomicInteger pv;
public PageViewListener() {
System.out.println("PageViewListener被建立");
pv = new AtomicInteger(0);
}
public void requestDestroyed(ServletRequestEvent sre) {
}
public void requestInitialized(ServletRequestEvent sre) {
System.out.println(pv.incrementAndGet());
}
此監聽器在Tomcat啟動時被建立
使用AtomicInteger pv當作計數器。
每次收到客戶端的request就會觸發一次requestInitialized()。